package com.brainwave.bluetooth;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;

import androidx.core.app.ActivityCompat;

import com.brainwave.utils.Constants;
import com.brainwave.utils.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * 蓝牙管理器类
 * 负责蓝牙设备的搜索、连接、数据传输和状态管理
 */
public class BluetoothManager {
    private static final String TAG = "BluetoothManager";
    
    // 蓝牙适配器
    private BluetoothAdapter bluetoothAdapter;
    private Context context;
    private Handler mainHandler;
    
    // 连接相关
    private BluetoothSocket bluetoothSocket;
    private BluetoothDevice connectedDevice;
    private ConnectThread connectThread;
    private ConnectedThread connectedThread;
    
    // 状态管理
    private ConnectionState connectionState = ConnectionState.DISCONNECTED;
    private List<BluetoothConnectionListener> listeners = new ArrayList<>();
    
    // 设备搜索
    private List<BluetoothDevice> discoveredDevices = new ArrayList<>();
    private boolean isScanning = false;
    
    /**
     * 连接状态枚举
     */
    public enum ConnectionState {
        DISCONNECTED,
        CONNECTING,
        CONNECTED,
        DISCONNECTING,
        ERROR
    }
    
    /**
     * 蓝牙连接监听器接口
     */
    public interface BluetoothConnectionListener {
        void onConnectionStateChanged(ConnectionState state);
        void onDeviceFound(BluetoothDevice device);
        void onDataReceived(byte[] data);
        void onError(String error);
    }
    
    /**
     * 构造函数
     */
    public BluetoothManager(Context context) {
        this.context = context.getApplicationContext();
        this.mainHandler = new Handler(Looper.getMainLooper());
        this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        
        // 注册蓝牙状态变化广播接收器
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        context.registerReceiver(bluetoothReceiver, filter);
        
        Logger.d(TAG, "BluetoothManager initialized");
    }
    
    /**
     * 检查蓝牙是否可用
     */
    public boolean isBluetoothAvailable() {
        return bluetoothAdapter != null;
    }
    
    /**
     * 检查蓝牙是否已启用
     */
    public boolean isBluetoothEnabled() {
        return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
    }
    
    /**
     * 检查蓝牙权限
     */
    public boolean hasBluetoothPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            return ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED &&
                   ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED;
        } else {
            return ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED &&
                   ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED;
        }
    }
    
    /**
     * 添加连接监听器
     */
    public void addConnectionListener(BluetoothConnectionListener listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除连接监听器
     */
    public void removeConnectionListener(BluetoothConnectionListener listener) {
        listeners.remove(listener);
    }
    
    /**
     * 开始搜索蓝牙设备
     */
    public boolean startDiscovery() {
        if (!hasBluetoothPermissions()) {
            notifyError("Missing bluetooth permissions");
            return false;
        }
        
        if (!isBluetoothEnabled()) {
            notifyError("Bluetooth is not enabled");
            return false;
        }
        
        if (isScanning) {
            stopDiscovery();
        }
        
        discoveredDevices.clear();
        isScanning = true;
        
        // 首先获取已配对的设备
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        for (BluetoothDevice device : pairedDevices) {
            if (isNeuroSkyDevice(device)) {
                discoveredDevices.add(device);
                notifyDeviceFound(device);
            }
        }
        
        // 开始搜索新设备
        boolean started = bluetoothAdapter.startDiscovery();
        if (started) {
            Logger.d(TAG, "Started bluetooth discovery");
        } else {
            isScanning = false;
            notifyError("Failed to start bluetooth discovery");
        }
        
        return started;
    }
    
    /**
     * 停止搜索蓝牙设备
     */
    public void stopDiscovery() {
        if (hasBluetoothPermissions() && bluetoothAdapter.isDiscovering()) {
            bluetoothAdapter.cancelDiscovery();
        }
        isScanning = false;
        Logger.d(TAG, "Stopped bluetooth discovery");
    }
    
    /**
     * 连接到指定的蓝牙设备
     */
    public void connectToDevice(BluetoothDevice device) {
        if (connectionState == ConnectionState.CONNECTING || connectionState == ConnectionState.CONNECTED) {
            Logger.w(TAG, "Already connecting or connected");
            return;
        }
        
        if (!hasBluetoothPermissions()) {
            notifyError("Missing bluetooth permissions");
            return;
        }
        
        stopDiscovery();
        disconnect();
        
        connectThread = new ConnectThread(device);
        connectThread.start();
        
        Logger.d(TAG, "Connecting to device: " + device.getName());
    }
    
    /**
     * 断开蓝牙连接
     */
    public void disconnect() {
        setConnectionState(ConnectionState.DISCONNECTING);
        
        if (connectedThread != null) {
            connectedThread.cancel();
            connectedThread = null;
        }
        
        if (connectThread != null) {
            connectThread.cancel();
            connectThread = null;
        }
        
        if (bluetoothSocket != null) {
            try {
                bluetoothSocket.close();
            } catch (IOException e) {
                Logger.e(TAG, "Error closing socket", e);
            }
            bluetoothSocket = null;
        }
        
        connectedDevice = null;
        setConnectionState(ConnectionState.DISCONNECTED);
        
        Logger.d(TAG, "Disconnected from bluetooth device");
    }
    
    /**
     * 发送数据
     */
    public boolean sendData(byte[] data) {
        if (connectedThread != null && connectionState == ConnectionState.CONNECTED) {
            connectedThread.write(data);
            return true;
        }
        return false;
    }
    
    /**
     * 获取当前连接状态
     */
    public ConnectionState getConnectionState() {
        return connectionState;
    }
    
    /**
     * 获取已连接的设备
     */
    public BluetoothDevice getConnectedDevice() {
        return connectedDevice;
    }
    
    /**
     * 获取发现的设备列表
     */
    public List<BluetoothDevice> getDiscoveredDevices() {
        return new ArrayList<>(discoveredDevices);
    }
    
    /**
     * 判断是否为NeuroSky设备
     */
    private boolean isNeuroSkyDevice(BluetoothDevice device) {
        if (!hasBluetoothPermissions()) {
            return false;
        }
        
        String deviceName = device.getName();
        if (deviceName == null) {
            return false;
        }
        
        // 检查设备名称是否包含NeuroSky相关关键词
        for (String name : Constants.NEUROSKY_DEVICE_NAMES) {
            if (deviceName.toLowerCase().contains(name.toLowerCase())) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 设置连接状态
     */
    private void setConnectionState(ConnectionState state) {
        if (connectionState != state) {
            connectionState = state;
            mainHandler.post(() -> {
                for (BluetoothConnectionListener listener : listeners) {
                    listener.onConnectionStateChanged(state);
                }
            });
        }
    }
    
    /**
     * 通知设备发现
     */
    private void notifyDeviceFound(BluetoothDevice device) {
        mainHandler.post(() -> {
            for (BluetoothConnectionListener listener : listeners) {
                listener.onDeviceFound(device);
            }
        });
    }
    
    /**
     * 通知数据接收
     */
    private void notifyDataReceived(byte[] data) {
        mainHandler.post(() -> {
            for (BluetoothConnectionListener listener : listeners) {
                listener.onDataReceived(data);
            }
        });
    }
    
    /**
     * 通知错误
     */
    private void notifyError(String error) {
        Logger.e(TAG, error);
        mainHandler.post(() -> {
            for (BluetoothConnectionListener listener : listeners) {
                listener.onError(error);
            }
        });
    }
    
    /**
     * 蓝牙广播接收器
     */
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null && isNeuroSkyDevice(device)) {
                    if (!discoveredDevices.contains(device)) {
                        discoveredDevices.add(device);
                        notifyDeviceFound(device);
                    }
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                isScanning = false;
                Logger.d(TAG, "Bluetooth discovery finished");
            } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                if (state == BluetoothAdapter.STATE_OFF) {
                    disconnect();
                }
            }
        }
    };
    
    /**
     * 连接线程
     */
    private class ConnectThread extends Thread {
        private final BluetoothSocket socket;
        private final BluetoothDevice device;
        
        public ConnectThread(BluetoothDevice device) {
            this.device = device;
            BluetoothSocket tmp = null;
            
            try {
                if (hasBluetoothPermissions()) {
                    // 使用标准的SPP UUID
                    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
                    tmp = device.createRfcommSocketToServiceRecord(uuid);
                }
            } catch (IOException e) {
                Logger.e(TAG, "Socket create() failed", e);
            }
            
            socket = tmp;
        }
        
        public void run() {
            setConnectionState(ConnectionState.CONNECTING);
            
            if (socket == null) {
                setConnectionState(ConnectionState.ERROR);
                notifyError("Failed to create socket");
                return;
            }
            
            try {
                if (hasBluetoothPermissions()) {
                    socket.connect();
                }
                
                bluetoothSocket = socket;
                connectedDevice = device;
                
                // 启动数据传输线程
                connectedThread = new ConnectedThread(socket);
                connectedThread.start();
                
                setConnectionState(ConnectionState.CONNECTED);
                Logger.d(TAG, "Connected to " + device.getName());
                
            } catch (IOException e) {
                Logger.e(TAG, "Unable to connect to device", e);
                try {
                    socket.close();
                } catch (IOException closeException) {
                    Logger.e(TAG, "Unable to close socket during connection failure", closeException);
                }
                setConnectionState(ConnectionState.ERROR);
                notifyError("Connection failed: " + e.getMessage());
            }
        }
        
        public void cancel() {
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                Logger.e(TAG, "close() of connect socket failed", e);
            }
        }
    }
    
    /**
     * 数据传输线程
     */
    private class ConnectedThread extends Thread {
        private final BluetoothSocket socket;
        private final InputStream inputStream;
        private final OutputStream outputStream;
        private volatile boolean running = true;
        
        public ConnectedThread(BluetoothSocket socket) {
            this.socket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Logger.e(TAG, "Error occurred when creating input/output streams", e);
            }
            
            inputStream = tmpIn;
            outputStream = tmpOut;
        }
        
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            
            while (running) {
                try {
                    bytes = inputStream.read(buffer);
                    if (bytes > 0) {
                        byte[] data = new byte[bytes];
                        System.arraycopy(buffer, 0, data, 0, bytes);
                        notifyDataReceived(data);
                    }
                } catch (IOException e) {
                    if (running) {
                        Logger.e(TAG, "Input stream was disconnected", e);
                        setConnectionState(ConnectionState.ERROR);
                        notifyError("Connection lost");
                    }
                    break;
                }
            }
        }
        
        public void write(byte[] bytes) {
            try {
                outputStream.write(bytes);
                outputStream.flush();
            } catch (IOException e) {
                Logger.e(TAG, "Error occurred when sending data", e);
                notifyError("Failed to send data");
            }
        }
        
        public void cancel() {
            running = false;
            try {
                socket.close();
            } catch (IOException e) {
                Logger.e(TAG, "close() of connect socket failed", e);
            }
        }
    }
    
    /**
     * 释放资源
     */
    public void destroy() {
        try {
            context.unregisterReceiver(bluetoothReceiver);
        } catch (IllegalArgumentException e) {
            // 接收器可能已经被注销
        }
        
        disconnect();
        listeners.clear();
        
        Logger.d(TAG, "BluetoothManager destroyed");
    }
}